import { Controller, Post, Body, ParseIntPipe, HttpException, HttpStatus, UseGuards } from '@nestjs/common';
import { ApiBody, ApiOkResponse, ApiOperation, ApiTags, getSchemaPath } from '@nestjs/swagger';
import { AuthService } from './auth.service';
import { CreateRoleDto, CreateUserDto, RoleAuthConfigDto, RoleUserDto } from './dto/create-auth.dto';
import { UpdateRoleDto, UpdateRoleMenuActionDto, UpdateUserDto } from './dto/update-auth.dto';
import { FindManyOptions } from 'typeorm';
import { SysRole } from './entities/auth.entity';
import { SqlQueryPipe } from '@/common/pipe/sqlquery.pipe';
import { DeleteDto, ResponseJson, SqlQueryDto } from '@/common/type/app.dto';
import { RoleConfigAuthPipe } from './auth.pipe';
import { SysUser } from '@/sys/entities/sys.entity';
import { AuthGuard } from '@/common/guard/auth.guard';
import { UpdateSysActionDto, UpdateSysMenuDto } from '@/sys/dto/update-sy.dto';
import { CrudService } from '@/shared/crud.service';
@Controller('auth')
@ApiTags('权限管理')
@UseGuards(AuthGuard)
export class AuthController {
    constructor(private readonly authService: AuthService,
        private crud: CrudService,
    ) { }

    @Post('roles')
    @ApiOperation({ summary: '角色查询' })
    @ApiBody({ type: SqlQueryDto })
    @ApiOkResponse({
        schema: {
            allOf: [
                { $ref: getSchemaPath(ResponseJson) },
                {
                    properties: {
                        obj: {
                            type: 'array',
                            description: '角色数组',
                            items: {
                                $ref: getSchemaPath(UpdateRoleDto)
                            }
                        }
                    },

                }
            ]
        }
    })
    async getRoles(@Body() query: SqlQueryDto) /* query: SqlQueryDto, */
        : Promise<ResponseJson<SysRole[], number>> {
        return await this.crud.query<SysRole>(SysRole, query);
    }
    @Post('rolecreate')
    @ApiOperation({ summary: '创建角色' })
    @ApiOkResponse({
        schema: {
            allOf: [
                { $ref: getSchemaPath(ResponseJson) },
                {
                    properties: {
                        obj: {
                            type: 'object',
                            description: '角色',
                            $ref: getSchemaPath(UpdateRoleDto)
                        }
                    },

                }
            ]
        }
    })
    async createRole(@Body() createRoleDto: CreateRoleDto) {
        return await this.authService.createRole(createRoleDto);
    }

    @Post('roleupdate')
    @ApiOperation({ summary: '修改角色' })
    @ApiOkResponse({ type: ResponseJson })
    async updateRole(@Body() upadteRoleDto: UpdateRoleDto) {
        return await this.authService.updateRole(upadteRoleDto);
    }

    @Post('roledelete')
    @ApiOperation({ summary: '删除角色' })
    @ApiOkResponse({ type: ResponseJson })
    async deleteRole(@Body() ids: DeleteDto) {
        return this.authService.deleteRole(ids);
    }

    @Post('getmenutreebyrole')
    @ApiOperation({ summary: '取角色菜单tree' })
    @ApiBody({
        type: 'object',
        schema: {
            properties: {
                roleId: {
                    type: 'number',
                    description: '角色ID',
                }
            }
        }
    })
    @ApiOkResponse({
        schema: {
            allOf: [
                { $ref: getSchemaPath(ResponseJson) },
                {
                    properties: {
                        obj: {
                            type: 'array',
                            description: '菜单',
                            items: {
                                $ref: getSchemaPath(UpdateSysMenuDto)
                            }
                        }
                    }
                }
            ]
        },
    })
    async getRoleMenuTree(@Body('roleId', new ParseIntPipe({
        exceptionFactory: (e) => new HttpException('角色参数错误', HttpStatus.BAD_REQUEST)
    })) roleId: number) {
        return this.authService.getRoleMenuTree(roleId);
    }

    @Post('getactionsbyrolemenu')
    @ApiOperation({ summary: '取角色菜单关联的功能' })
    @ApiOkResponse({
        schema: {
            allOf: [
                { $ref: getSchemaPath(ResponseJson) },
                {
                    properties: {
                        obj: {
                            type: 'array',
                            description: '菜单关联的所有功能',
                            items: {
                                $ref: getSchemaPath(UpdateSysActionDto)
                            }
                        },
                        ext: {
                            type: 'array',
                            description: '此角色+菜单已关联的功能',
                            items: {
                                type: 'number'
                            }
                        }
                    }
                }
            ]
        },
    })
    async getActionsByRoleMenu(@Body() param: UpdateRoleMenuActionDto) {
        return this.authService.getActionsByRoleMenu(param.roleId, param.menuId);
    }

    @Post('configroleauth')
    @ApiOperation({ summary: '配置角色权限' })
    @ApiOkResponse({ type: ResponseJson })
    async createRoleMenuAction(@Body(RoleConfigAuthPipe) param: RoleAuthConfigDto) {

        return this.authService.configRoleAuth(param);
    }

    @Post('users')
    @ApiOperation({ summary: '用户查询' })
    @ApiBody({ type: SqlQueryDto })
    @ApiOkResponse({
        schema: {
            allOf: [
                { $ref: getSchemaPath(ResponseJson) },
                {
                    properties: {
                        obj: {
                            type: 'array',
                            description: '用户',
                            items: {
                                $ref: getSchemaPath(UpdateUserDto)
                            }
                        }
                    }
                }
            ]
        },
    })
    async getUsers(@Body(SqlQueryPipe) param: FindManyOptions<SysUser>) {
        return this.authService.getUsers(param);
    }

    @Post('usercreate')
    @ApiOperation({ summary: '创建用户' })
    @ApiOkResponse({
        schema: {
            allOf: [
                { $ref: getSchemaPath(ResponseJson) },
                {
                    properties: {
                        obj: {
                            type: 'object',
                            $ref: getSchemaPath(UpdateUserDto),
                            description: '用户',
                        }
                    }
                }
            ]
        },
    })
    async createUser(@Body() param: CreateUserDto) {
        return this.authService.createUser(param);
    }

    @Post('userupdate')
    @ApiOperation({ summary: '修改用户' })
    @ApiOkResponse({ type: ResponseJson })
    async updateUser(@Body() param: UpdateUserDto) {
        return this.authService.updateUser(param);
    }

    @Post('userdelete')
    @ApiOperation({ summary: '删除用户' })
    @ApiOkResponse({ type: ResponseJson })
    async deleteUsers(@Body() param: DeleteDto) {
        return this.authService.deleteUsers(param);
    }

    @Post('resetpass')
    @ApiOperation({ summary: '重置密码' })
    @ApiOkResponse({ type: ResponseJson })
    async resetPass(@Body() param: DeleteDto) {
        return this.authService.resetPassword(param);
    }

    @Post('getusersbyrole')
    @ApiOperation({ summary: '角色用户查询' })
    @ApiBody({
        type: 'object',
        schema: {
            properties: {
                roleId: {
                    type: 'number',
                    description: '角色ID',
                }
            }
        }
    })
    @ApiOkResponse({
        schema: {
            allOf: [
                { $ref: getSchemaPath(ResponseJson) },
                {
                    properties: {
                        obj: {
                            type: 'array',
                            description: '用户数组',
                            $ref: getSchemaPath(UpdateUserDto)
                        }
                    }
                }
            ]
        }
    })
    async getUsersByRole(@Body('roleId', new ParseIntPipe({
        exceptionFactory: (e) => new HttpException('角色参数错误', HttpStatus.BAD_REQUEST)
    })) roleId: number) {
        return this.authService.getUsersByRole(roleId);
    }

    @Post('configroleuser')
    @ApiOperation({ summary: '角色用户维护' })
    @ApiOkResponse({ type: ResponseJson })
    async configRoleUser(@Body() param: RoleUserDto) {
        return this.authService.configRoleUser(param);
    }
}
